package com.yaperviy.spider;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.Vector;

import com.yaperviy.dao.BrandDao;
import com.yaperviy.model.*;
import com.yaperviy.service.GenericManager;
import com.yaperviy.service.impl.GenericManagerImpl;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


import com.yaperviy.dao.GenericDao;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;



public class ModelPopulator {
	

	
	private GenericManager<Brand, Long> brandManager;
	private GenericManager<Model, Long> modelManager; 
	
	//from where to fetch models
	private static final String brandSearchURL = "http://cars.auto.ru";
	
	//cut of central block
	private static final String blockBegin = "<!--- BEGIN CENTER_BLOCK -->";
	private static final String blockEnd = "<!--- END CENTER_BLOCK -->";
	
	//cut of cars table
	private static final String tableBegin = "<table cellpadding=\"0\" cellspacing=\"0\" class=\"list\">";
	private static final String tableEnd = "</table>";
	

	//cut of table <td>s
	private static final String brandTdBegin = "<td><div class=\"cell-1\">";
	private static final String brandTdEnd = "<!--- END CENTER_BLOCK -->";
	
	
	//crop links to model list
	private static final String divPreSplit = "<div class=\"cell-1\">";
	private static final String divPostSplit = "></div>";

	//crop urls and names
	private static final String urlBegin = "<a href=\"";
	private static final String boldUrlEnd = "\" style=font-weight:bold>"; 
	private static final String urlEnd = "\">";
	private static final String titleBegin = ">";
	private static final String titleEnd = "</a";
	
	
	//models parsing constants
	private static final String modelTrPreSplit = "<tr class=group><td>";
	private static final String modelTitleBegin = ">";
	private static final String modelTitleEnd = "<";
	
	class SiteCarBrand {
		String url;
		String title;
		Boolean isRus;
		SiteCarBrand(String url, String title, Boolean isRus) {
			this.url = url;
			this.title = title;
			this.isRus = isRus;
		}
	}


	Log log = LogFactory.getLog(ModelPopulator.class);

	public ModelPopulator() {
		
		ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
		        new String[] {"classpath:/applicationContext-resources.xml", "classpath:/applicationContext-dao.xml", "classpath*:/applicationContext.xml", "classpath:**/applicationContext*.xml"});
		BeanFactory factory = (BeanFactory) appContext;	
		brandManager = (GenericManager<Brand, Long>) factory.getBean("brandManager");
		modelManager = (GenericManager<Model, Long>) factory.getBean("modelManager"); 
	} 
	

	public ArrayList<SiteCarBrand> populateBrands() {
		
		//define variables
		
		Vector modelsAndURLs = new Vector();
		ArrayList<SiteCarBrand> rusBrands = new ArrayList();
		ArrayList<SiteCarBrand> impBrands = new ArrayList();
		ArrayList<String> brandModels = new ArrayList();
		
		String response = "";
		String rusCarsTable = "";
		String impCarsTable = "";
		
		
		//get the HTML of brand page
		response = HTTPRequestPoster.sendGetRequest(brandSearchURL, "");
		
		//crop the central block
		response = response.substring(response.indexOf(blockBegin) + blockBegin.length(), response.indexOf(blockEnd));
		
		try {
			int rusTableBegin = response.indexOf(tableBegin)
					+ tableBegin.length();
			int rusTableEnd = response.indexOf(tableEnd) + tableEnd.length();

			// get the Russian and import cars tables
			rusCarsTable = response.substring(rusTableBegin, rusTableEnd);

			// log.debug("RUSSIAN TABLE \n" + rusCarsTable);

			// cut the Russian cars out
			response = response.substring(rusTableEnd);

			int startImportTableIndex = response.indexOf(tableBegin)
					+ tableBegin.length();
			int endImportTableIndex = response.indexOf(tableEnd,
					startImportTableIndex);

			impCarsTable = response.substring(startImportTableIndex,
					endImportTableIndex);

			rusBrands = populateBrandsFromCarsTable(rusCarsTable, true);
			impBrands = populateBrandsFromCarsTable(impCarsTable, false);

			Iterator<SiteCarBrand> impBrandsIterator = impBrands.iterator();
			while (impBrandsIterator.hasNext()) {
				rusBrands.add(impBrandsIterator.next());
			}
			
			//rusBrands now actually represent all brands
			Iterator<SiteCarBrand> allBrandsIterator = rusBrands.iterator();
			
			int i = 0;
			while (allBrandsIterator.hasNext()) {
				i++;
				if(i>3) {break;}
				SiteCarBrand currentBrand = allBrandsIterator.next();
				Brand brand = new Brand();
				brand.setTitle(currentBrand.title);
				brand.setIs_rus(currentBrand.isRus);
				log.debug("brandDao.hash = "+ brandManager.hashCode());
				log.debug("brand.hash = "+ brand.hashCode());
				brand = brandManager.save(brand);
				
				brandModels = populateModels(currentBrand.url);
				
				Iterator<String> brandModelsIterator = brandModels.iterator();
				while (brandModelsIterator.hasNext()) {
					Model model = new Model();
					model.setBrand_id(brand.getId());
					model.setTitle(brandModelsIterator.next());
					modelManager.save(model);
				}
				
			}
			
			
		} catch (Exception e) {
			e.printStackTrace();
			log.error("Error parsing the brand page");
		}
		//populateModels("/cars/used/honda/");
		
		
		return rusBrands;
	}
	
	private ArrayList<String> populateModels(String url) {
		
		String response = "";
		ArrayList<String> modelTitles = new ArrayList<String>();
		//get the HTML of brand page
		response = HTTPRequestPoster.sendGetRequest(brandSearchURL+url, "");
		response = response.substring(response.indexOf(blockBegin));
		
		String[] anchors = response.split(modelTrPreSplit);
		
		//first chunk is shit, the second is "all models"
		for(int i=2; i<anchors.length; i++) {
			int titleBeginIndex = anchors[i].indexOf(modelTitleBegin);
			int titleEndIndex = anchors[i].indexOf(modelTitleEnd, titleBeginIndex);
			if(titleBeginIndex < 0 || titleEndIndex < 0) { 
				break;
			} else {
				modelTitles.add(anchors[i].substring(titleBeginIndex + modelTitleBegin.length(), titleEndIndex));
				log.debug(anchors[i].substring(titleBeginIndex + modelTitleBegin.length(), titleEndIndex));
			}
		}
		return modelTitles;
	}
	
	
	private ArrayList<SiteCarBrand> populateBrandsFromCarsTable(String carsTable, Boolean isRus) {
		
		ArrayList<SiteCarBrand> brands = new ArrayList<SiteCarBrand>();

		//now lets get the links only to model list
		String[] anchors = carsTable.split(divPreSplit);
		
		//start from 2nd chunk as because 1st is trash and crop the anchors
		
		for(int i=1; i<anchors.length; i++) {
			int anchorEndIndex = anchors[i].indexOf(divPostSplit);
			if(anchorEndIndex > 0) {
				anchors[i] = anchors[i].substring(0, anchorEndIndex);
				
			}
		}
		
		for(int i=1; i<anchors.length; i++) {
			int urlBeginIndex = anchors[i].indexOf(urlBegin) + urlBegin.length();
			int urlEndIndex = 0;

			if(anchors[i].indexOf(boldUrlEnd) < 0) {
				urlEndIndex = anchors[i].indexOf(urlEnd); 
			}else{
				urlEndIndex = anchors[i].indexOf(boldUrlEnd);
			}
			
			if(urlEndIndex < 0 || urlBeginIndex < 0) break;
			

			String url = anchors[i].substring(urlBeginIndex, urlEndIndex);
			String title = anchors[i].substring(anchors[i].indexOf(titleBegin) + titleBegin.length(), anchors[i].indexOf(titleEnd));
			
			brands.add(new SiteCarBrand(url, title, isRus));
		}
		return brands;		
	}
	

}
